import re

from datetime import datetime
from pymongo import MongoClient


def parse_info_line(info_line):
  # Name: numerical_value
  pattern = r'([a-zA-Z]+: [-+]*[0-9]+(.[0-9]+)*)'
  env = {}
  for item in re.findall(pattern, info_line):
    exec(item[0].replace(':', '='), env)
  return env


class KimchiParser(object):
  def __init__(self, db_name, *, on_push, dry_run=False, push_fill=False):
    self._storage = {}
    self._db_name = db_name
    self._db = MongoClient(
        'mongodb://inkyu_legacy:xArT3T#dXtGfSBDV@13.251.33.84:42006/coin_20181121'
    ).legacy_20181201[db_name]
    self._pnl = MongoClient(
        'mongodb://inkyu_legacy:xArT3T#dXtGfSBDV@13.251.33.84:42006/coin_20181121'
    ).pnl_20181201[db_name]
    self._timestamp = None
    self._state = 0
    self._krw = None
    self._usdt = None
    self._push_fill = push_fill
    self._on_push = on_push
    self._dry_run = dry_run

  def _push_legacy(self, payload):
    self._on_push(self._db_name, 'chart', payload)
    if not self._dry_run:
      self._db.insert_one(payload)

  def _push_pnl(self, payload):
    self._on_push(self._db_name, 'pnl', payload)
    if not self._dry_run:
      self._pnl.insert_one(payload)

  def handle(self, line):
    if line.startswith('* 2018'):
      self._timestamp = datetime.strptime(line[2:-1], '%Y-%m-%d %H:%M:%S.%f')
      self._storage['timestamp'] = self._timestamp
    elif line.startswith(' KRW: ') or line.startswith(' USDT: '):
      parsed = parse_info_line(line)
      self._krw = parsed['KRW']
      self._usdt = parsed['USDT']
    elif line.startswith('Position'):
      parsed = parse_info_line(line)
      dkrw = parsed['PositionKRW']
      dusdt = parsed['PositionUSDT']
      if dkrw != 0:
        self._push_legacy({'timestamp': self._timestamp, 'tag': 'KRW', 'value': self._krw + dkrw})
        self._push_legacy({
            'timestamp': self._timestamp, 'tag': 'USDT', 'value': self._usdt + dusdt
        })
        self._storage['krw'] = self._krw
        self._storage['usdt'] = self._usdt
        self._storage['krw_pos'] = dkrw
        self._storage['usdt_pos'] = dusdt
    elif line.startswith('Balance'):
      parsed = parse_info_line(line)
      dkrw = parsed['BalanceKRW']
      dusdt = parsed['BalanceUSDT']
      if dkrw != 0:
        self._storage['krw_bal'] = dkrw
        self._storage['usdt_bal'] = dusdt
    elif line.startswith('Reserve'):
      parsed = parse_info_line(line)
      dkrw = parsed['ReserveKRW']
      dusdt = parsed['ReserveUSDT']
      if dkrw != 0:
        self._storage['krw_reserve'] = dkrw
        self._storage['usdt_reserve'] = dusdt
    elif line.startswith('MasterPrices'):
      splitted = re.split('[ ()=]+', line)
      gmean_price = float(splitted[2][:-1])
      ema_price = float(splitted[4][:-1])
      self._push_legacy({'timestamp': self._timestamp, 'tag': 'GMEAN_PRICE', 'value': gmean_price})
      self._push_legacy({'timestamp': self._timestamp, 'tag': 'EMA_PRICE', 'value': ema_price})
      self._storage['ema_price'] = ema_price
      self._storage['gmean_price'] = gmean_price
      if 'krw' in self._storage:
        self._push_pnl(self._storage)
      self._storage = {}
    elif '~' in line:
      splitted = re.split('[ ()=~]+', line)
      price1 = float(splitted[-2])
      price2 = float(splitted[-3])
      price = (price1 + price2) / 2
      ds_str = '2018 %s %s' % (splitted[0][1:], splitted[1])
      self._timestamp = datetime.strptime(ds_str, '%Y %m%d %H:%M:%S.%f')
      action = splitted[5]
      if self._push_fill:
        self._push_legacy({'timestamp': self._timestamp, 'tag': action, 'value': price})
